// ==UserScript==
// @name         GGMR - 全局GitHub镜像重定向工具：高效、灵活、易用 (Global GitHub Mirror Redirector)
// @namespace    https://gitee.com/AningMicroHoard/Global-GitHub-Mirror-Redirector/
// @version      1.3.1
// @description  全局GitHub镜像重定向工具（可配置镜像地址）| 镜像站安全警告显示 | Releases多源加速
// @author       Aning
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // ===================== 配置区域 =====================
    const MIRROR_DOMAIN = 'bgithub.xyz'; // 国内推荐镜像：https://fcp7.com/github-mirror-daily-updates.html
    const RELEASES_MIRRORS = [            // Releases加速镜像配置
        {
            name: "直接下载",
            url: `https://${MIRROR_DOMAIN}`,
            desc: "当前镜像站下载"
        },
        {
            name: "github下载",
            url: `https://github.com`,
            desc: "github官网下载"
        },
        {
            name: "moeyy代理",
            url: "https://github.moeyy.xyz/https://github.com",
            desc: "github.moeyy.xyz代理"
        },
        {
            name:"llkk代理",
            url:"https://gh.llkk.cc/https://github.com",
            desc: "gh.llkk.cc代理"
        },
        {
            name:"isteed代理",
            url:"https://cors.isteed.cc/github.com",
            desc:"cors.isteed.cc代理-[美国 Cloudflare CDN] - 该公益加速源由 [@Lufs\'s] 提供"
        },
        {
            name:"ygxz代理",
            url:"https://gh-proxy.ygxz.in/https://github.com",
            desc:"gh-proxy.ygxz.in代理 - 该公益加速源由 [@一个小站] 提供"
        }
    ];
    // ===================================================

    // 镜像站安全警告逻辑
    if (window.location.hostname === MIRROR_DOMAIN) {
        // 创建警告条
        const warningBar = document.createElement('div');
        warningBar.innerHTML = '<strong>安全警告：</strong>请勿在镜像站登录！可能导致账号泄露！';

        // 样式配置
        warningBar.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            background: #dc3545;
            color: white;
            padding: 12px 20px;
            text-align: center;
            z-index: 2147483647;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            font-size: 14px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
        `;

        // 添加图标
        warningBar.insertAdjacentHTML('afterbegin', '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L3 21h18L12 2zm0 6v6m0 2v-2"/></svg>');

        // 插入到页面顶部
        document.documentElement.prepend(warningBar);

        // 动态调整页面布局
        const adjustLayout = () => {
            const barHeight = warningBar.offsetHeight;
            document.body.style.marginTop = `${barHeight}px`;
            document.body.style.scrollMarginTop = `${barHeight}px`; // 处理锚点定位
        };

        // 初始调整
        adjustLayout();

        // 监听窗口变化
        window.addEventListener('resize', adjustLayout);
    }

    // 自动重定向GitHub请求
    const shouldRedirect = window.location.host.match(/\.?github\.com$/i);
    if (shouldRedirect) {
        const newUrl = window.location.href.replace(
            /(https?:\/\/)([a-z0-9-]+\.)*github\.com/gi,
            `$1${MIRROR_DOMAIN}`
        );
        if (newUrl !== window.location.href) {
            window.location.replace(newUrl);
            return;
        }
    }

    // ================== Releases加速功能优化版 ==================
    // 检测是否在Releases页面
    const isReleasesPage = /^\/[^/]+\/[^/]+\/releases($|\/)/i.test(window.location.pathname);

    // 添加加速下载按钮（新增防替换标记）
    function addReleaseButtons() {
        const releaseItems = document.querySelectorAll('.Box-row:not([data-processed])');

        releaseItems.forEach(item => {
            item.dataset.processed = 'true';

            const originalLink = item.querySelector('a[href*="/releases/download/"]');
            if (!originalLink) return;

            // 修复原始URL获取逻辑
            const originalUrl = originalLink.href;
            const rawGitHubUrl = originalUrl.replace(`https://${MIRROR_DOMAIN}`, 'https://github.com');
            const urlObj = new URL(rawGitHubUrl);
            const path = urlObj.pathname + urlObj.search + urlObj.hash;

            // 创建按钮容器
            const btnContainer = document.createElement('div');
            btnContainer.className = 'multi-source-download';
            btnContainer.style.cssText = `
                margin-top: 8px;
                display: flex;
                gap: 6px;
                flex-wrap: wrap;
            `;

            // 生成带防替换标记的按钮
            RELEASES_MIRRORS.forEach(mirror => {
                const btn = document.createElement('a');
                btn.href = mirror.url + path;
                btn.setAttribute('data-mirror-link', 'true'); // 关键标记
                btn.target = '_blank';
                btn.rel = 'noopener noreferrer';
                btn.title = `${mirror.desc}\n${mirror.url}`;
                btn.style.cssText = `
        display: inline-flex;
        align-items: center;
        padding: 5px 12px;
        background: #f6f8fa;
        border: 1px solid rgba(27,31,36,0.15);
        border-radius: 6px;
        font-size: 12px;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
        color: #24292f;
        text-decoration: none;
        transition: 80ms cubic-bezier(0.33, 1, 0.68, 1);
        transition-property: background, border-color;
        cursor: pointer;
        margin-left: 8px;
        line-height: 1.5;
        box-shadow: 0 1px 0 rgba(27,31,36,0.04);

        &:hover {
            background-color: #f3f4f6;
            border-color: rgba(27,31,36,0.3);
            box-shadow: 0 1px 0 rgba(27,31,36,0.1);
        }

        &:active {
            background-color: #ebecf0;
            border-color: rgba(27,31,36,0.3);
            transition-duration: 0.1s;
        }
    `;
                btn.textContent = `${mirror.name}`;

                // 悬停效果
                btn.addEventListener('mouseenter', () => {
                    btn.style.background = '#0969da';
                    btn.style.color = 'white';
                });
                btn.addEventListener('mouseleave', () => {
                    btn.style.background = '#f6f8fa';
                    btn.style.color = '#24292f';
                });

                btnContainer.appendChild(btn);
            });

            item.appendChild(btnContainer);
        });
    }

    // 动态加载处理
    if (isReleasesPage) {
        // 初始处理
        addReleaseButtons();

        // 使用MutationObserver监听DOM变化
        const observer = new MutationObserver(mutations => {
            mutations.forEach(mutation => {
                mutation.addedNodes.forEach(node => {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        addReleaseButtons();
                    }
                });
            });
        });

        observer.observe(document, {
            childList: true,
            subtree: true
        });
    }

    // ================== 全局链接替换功能 ==================
    // 创建动态正则表达式
    const createGitHubRegex = (prefix = '') => {
        const escaped = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        return new RegExp(`${escaped}github\\.com`, 'gi');
    };

    // 增强型替换逻辑
    const replaceGitHubLinks = (content) => {
        return content
            .replace(createGitHubRegex('(https?://)'), `$1${MIRROR_DOMAIN}`)
            .replace(createGitHubRegex('(wss?://)'), `$1${MIRROR_DOMAIN}`)
            .replace(/(["'])\/\/github\.com/gi, `$1//${MIRROR_DOMAIN}`)
            .replace(/(git@)github\.com/gi, `$1${MIRROR_DOMAIN}`)
            .replace(/(\/github\.com)/gi, `/${MIRROR_DOMAIN}`);
    };


    // DOM处理器
    // 增强型替换逻辑（新增排除标记检测）
    const processNode = (node) => {
        if (node.nodeType === Node.TEXT_NODE) {
            const newContent = replaceGitHubLinks(node.textContent);
            if (newContent !== node.textContent) {
                node.textContent = newContent;
            }
        } else if (node.nodeType === Node.ELEMENT_NODE) {
            // 新增防替换检测
            const isMirrorLink = node.hasAttribute('data-mirror-link');

            ['href', 'src', 'action', 'data-src', 'cite', 'formaction'].forEach(attr => {
                const value = node.getAttribute(attr);
                if (value && !isMirrorLink) { // 跳过带标记的元素
                    const newValue = replaceGitHubLinks(value);
                    if (newValue !== value) {
                        node.setAttribute(attr, newValue);
                    }
                }
            });

            if (node.tagName === 'IFRAME' && node.contentDocument) {
                processDOM(node.contentDocument);
            }
        }
    };

    // 递归遍历DOM
    const processDOM = (root) => {
        processNode(root);
        let child = root.firstChild;
        while (child) {
            processDOM(child);
            child = child.nextSibling;
        }
    };

    // 初始处理
    processDOM(document);

    // 动态内容监听
    new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    processDOM(node);
                }
            });
        });
    }).observe(document, {
        childList: true,
        subtree: true
    });

    // 拦截网络请求
    const interceptXHR = () => {
        const originalOpen = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function(method, url) {
            arguments[1] = replaceGitHubLinks(url);
            return originalOpen.apply(this, arguments);
        };
    };

    const interceptFetch = () => {
        const originalFetch = window.fetch;
        window.fetch = function(input, init) {
            if (typeof input === 'string') {
                input = replaceGitHubLinks(input);
            } else if (input instanceof Request) {
                input = new Request(replaceGitHubLinks(input.url), input);
            }
            return originalFetch(input, init);
        };
    };

    interceptXHR();
    interceptFetch();
})();